///////////////////////////////////////////////////////////
///////////////// Have an itch? Scratch it! ///////////////
///////////////////////// SCRATCH /////////////////////////
/////////////////////  A MUD  Server   ////////////////////
///////////////////// By: Jared Devall ////////////////////
/////////////////////      Thanks:     ////////////////////
/////////////////////  DIKU/Merc/ROM   ////////////////////
///////////////////// Aetas/Deus Gang  ////////////////////
/////////////////////       Beej       ////////////////////
///////////////////////////////////////////////////////////

#include "definitions.h"
#include <list>
#include "commands.h"
#include "commandTable.h"
#include "character.h"
#include "world.h"
#include "stringutil.h"
#include "split.h"
#include "timestamp.h"
#include "logs.h"
#include "functions.h"

using namespace std;

// Command definitions for commands beginning with the letters N through P
// (Keep in alphabetical order... it's MUCH easier)
CmdNorth::CmdNorth() {
	SetName( "north" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdNorth::Execute( Character* c, const std::string& args ) {
	std::string buf;
	std::string fromMessage;
	std::string toMessage;
	Exit* in = &( c->getRoom()->GetExit( NORTH ) );
	
	if ( !in->GetThere() ) {
		buf << "There is no exit that way.\n\r";
		c->Send( buf );
		return true;
	}
	else if ( in->GetDoor() && !in->GetOpen() ) {
		buf << "That door is closed.\n\r";
		c->Send( buf );
		return true;
	}
	else {
		Room* from = c->getRoom();
		Room* to = 0;
		if ( ( to = World::Instance().FindRoom( in->GetPoint() ) ) == NULL ) {
			c->Send( "You can't go there.\n\r" );
			std::string message = "Exit inconsistency: ";
			message << from->GetVnum() << " north to " << in->GetPoint();
			log( SERVER, message );
			return false;
		}

		fromMessage << c->getName() << " has left to the north.";
		toMessage << c->getName() << " has arrived from the south.";

		from->Remove( c );
		sendToRoom( from, fromMessage );
		sendToRoom( to, toMessage );
		to->Add( c );
		from->Remove( c );
		c->setRoom( World::Instance().FindRoom( to->GetVnum() )->GetVnum() );
		CmdLook Command;
		Command.Execute( c, "auto_look: north" );
	}

	return true;
}

CmdNotes::CmdNotes() {
	SetName( "notes" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdNotes::Execute( Character* c, const string& args ) {
	std::string buf;

	c->SetStatus( NEDIT );
	c->Send( "Welcome to your post office!\n\r" );

	return true;
}

CmdOedit::CmdOedit() {
	SetName( "oedit" );
	SetLevel( BUILDER );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdOedit::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string syntax = "syntax: oedit make <vnum>      creates a new object\n\r        oedit <vnum>           edits object <vnum>\n\r        oedit remove <vnum>    removes an object\n\r";
	std::string welcome = " Welcome to SEM (Symphony Edit Mode) for objects!\n\r";
	std::string arg1, arg2;
	int vnum = 0;
	std::list< Area* >::iterator a_it;
	std::list< Object* >::iterator o_it;

	split( args, arg1, arg2 );

	if ( arg1.empty() ) {
		c->Send( syntax );
		return false;
	} else if ( arg2.empty() ) {
		// They want to edit an existing object...
		vnum = atoi( arg1.c_str() );
		if ( vnum <= 0 ) {
			// Validate vnum...
			c->Send( "That's an invalid vnum.\n\r" );
			return false;
		}
		// Find the object...
		for ( a_it = World::Instance().getAreas().begin(); a_it != World::Instance().getAreas().end(); a_it++ ) {
			for ( o_it = (*a_it)->getObjects().begin(); o_it != (*a_it)->getObjects().end(); o_it++ ) {
				if ( (*o_it)->getVnum() == vnum && World::Instance().findParentArea( vnum )->getPermission( c->getId() ) ) {
					// Found the object...
					c->SetStatus( OEDIT );
					c->setObject( *o_it );
					c->Send( welcome );
					return true;
				}
			}
		}
		// Object doesn't exist...
		c->Send( "That object doesn't exist.\n\r" );
		return false;
	} else if ( arg1 == "make" ) {
		// They want to create a new object...
		vnum = atoi( arg2.c_str() );
		if ( vnum <= 0 ) {
			// Validate vnum...
			c->Send( "That's an invalid vnum.\n\r" );
			return false;
		}
		// Make sure the object doesn't already exist...
		for ( a_it = World::Instance().getAreas().begin(); a_it != World::Instance().getAreas().end(); a_it++ ) {
			for ( o_it = (*a_it)->getObjects().begin(); o_it != (*a_it)->getObjects().end(); o_it++ ) {
				if ( (*o_it)->getVnum() == vnum ) {
					// Found the object...
					c->Send( "That object already exists!\n\r" );
					return false;
				}
			}
		}
		// Object doesn't exist... let's see if they have permission to the area...
		if ( World::Instance().findParentArea( vnum ) == NULL ) {
			c->Send( "That vnum doesn't exist!\n\r" );
			return false;
		} else {
			if ( !World::Instance().findParentArea( vnum )->getPermission( c->getId() ) ) {
				c->Send( "You don't have permissions to that vnum!\n\r" );
				return false;
			} else {
				// They've got the permissions; We'll go ahead and create the object now...
				Area* area = World::Instance().findParentArea( vnum );
				Object* obj = area->addObject();
				obj->setVnum( vnum );
				c->SetStatus( OEDIT );
				c->setObject( obj );
				c->Send( welcome );
				return true;
			}
		}
	} else if ( arg1 == "remove" ) {
		// They want to delete a object...
		vnum = atoi( arg2.c_str() );
		// Validate vnum...
		if ( vnum <= 0 ) {
			c->Send( "That's an invalid vnum.\n\r" );
			return false;
		}
		// Check permissions...
		if ( World::Instance().findParentArea( vnum ) == NULL ) {
			c->Send( "That vnum doesn't exist!\n\r" );
			return false;
		} else {
			if ( !World::Instance().findParentArea( vnum )->getPermission( c->getId() ) ) {
				c->Send( "You don't have permissions to that vnum!\n\r" );
				return false;
			}
		}
		// Find the object...
		for ( a_it = World::Instance().getAreas().begin(); a_it != World::Instance().getAreas().end(); a_it++ ) {
			for ( o_it = (*a_it)->getObjects().begin(); o_it != (*a_it)->getObjects().end(); o_it++ ) {
				if ( (*o_it)->getVnum() == vnum ) {
					// Found the mob...
					(*a_it)->getObjects().remove( *o_it );
					c->Send( "Object deleted.\n\r" );
					return true;
				}
			}
		}
		// Object not found...
		c->Send( "That object doesn't exist.\n\r" );
		return false;
	}

	// Something funky happened...
	c->Send( syntax );
	return false;
}

CmdOlist::CmdOlist() {
	SetName( "olist" );
	SetLevel( BUILDER );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdOlist::Execute( Character* c, const string& args ) {
	std::string buf;
	Area* area = 0;
	std::string tmp;
	std::string search = args;
	bool found = false;

	if ( args.empty() ) {
		c->Send( "syntax: olist all\n\r        olist <string>    (lists all objects with <string> in the name or short)\n\r" );
		return false;
	} else if ( args == "all" ) {
		// List all objects...
		for ( int i=0; i < (int)World::Instance().getAreas().size(); i++ ) {
			area = World::Instance().getArea( i );
			for ( std::list< Object* >::iterator it = area->getObjects().begin(); it != area->getObjects().end(); it++ )
				buf << "[ " << format( 5, (*it)->getVnum(), tmp, 'g' ) << "] " << (*it)->getShort() << "\n\r";
		}
		c->Send( buf );
		return true;
	} else {
		for ( int i=0; i < (int)World::Instance().getAreas().size(); i++ ) {
			// List only objects whose names/short descriptions contain the given string...
			area = World::Instance().getArea( i );
			for ( std::list< Object* >::iterator it = area->getObjects().begin(); it != area->getObjects().end(); it++ )
				if ( sub_str( search, (*it)->getKeywords() ) ) {
					found = true;
					buf << "[ " << format( 5, (*it)->getVnum(), tmp, 'g' ) << "] " << (*it)->getShort() << "\n\r";
				}
		}

		if ( !found ) {
			buf = "No objects were found with \"";
			buf << args << "\" in their name.\n\r";
		}

		c->Send( buf );
		return true;
	}

	c->Send( "{RERROR{x\n\r" );

	return false;
}

CmdOload::CmdOload() {
	SetName( "oload" );
	SetLevel( BUILDER );
	SetEnabled( true );
	SetOmniset( true );
}

bool CmdOload::Execute( Character* c, const string& args ) {
	std::string buf;
	std::list< Object* >::iterator it;
	int vnum = atoi( args.c_str() );
	Object* obj = 0;

	if ( !isdigit( args[0] ) ) {
		c->Send( "syntax: oload <vnum>\n\r" );
		return false;
	}

	if ( !args.empty() ) {
		for ( int i = 0; i < (int)World::Instance().getAreas().size(); i++ )
			for ( it = World::Instance().getArea( i )->getObjects().begin(); it != World::Instance().getArea( i )->getObjects().end(); it++ )
				if ( (*it)->getVnum() == vnum ) {
					obj = Object::getNewObject( (*it)->getType() );
					if ( obj == NULL ) {
						c->Send( "problem" );
						return false;
					}
					*obj = *(*it);
					c->getRoom()->Add( obj );
					c->setObject( obj );
					buf << c->getName() << " has created " << obj->getShort();
					sendToRoom( c->getRoom(), buf );
					buf = "You've loaded object ";
					buf << c->getObject()->getVnum() << ", \"" << c->getObject()->getShort() << "\"\n\r";
					c->Send( buf );
					return true;
				}
	}

	c->Send( "That object wasn't found.\n\r" );

	return false;
}

CmdOmninet::CmdOmninet() {
	SetName( "omninet" );
	SetLevel( BUILDER );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdOmninet::Execute( Character* c, const string& args ) {
	std::string buf;

	if ( args == "off" ) {
		c->SetOn( false );
		buf << "Omninet {roff{x.\n\r";
	} else if ( args == "on" ) {
		c->SetOn( true );
		buf << "Omninet {Gon{x.\n\r";
	} else {
		buf << "Omninet ";
		if ( c->GetOn() )
			buf << "{Gon";
		else
			buf << "{roff";
		buf << "{x.\n\r";
	}

	c->Send( buf );

	return true;
}

CmdOmniset::CmdOmniset() {
	SetName( "omniset" );
	SetLevel( HEAD );
	SetEnabled( true );
	SetOmniset( true );
}

bool CmdOmniset::Execute( Character* c, const string& args ) {
	std::string buf;
	Command* cmd = 0;
	std::list< Command* >::iterator it;
	int f = 0;
	std::string temp;

	if ( args.empty() ) {
		buf = " >> \"omniset\" toggles whether or not omninet reports a given command.\n\r\n\rsyntax: omniset <command name>\n\r\n\r";
		buf << "The following commands are omniset:\n\t{chead (level " << HEAD << "){x\n\r";
		for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it ) {
			if ( (*it)->_level == HEAD ) {
				if ( (*it)->_omniset ) {
					if ( !(*it)->_enabled )
						buf << "{w";
					if ( f == 0 ) {
						buf << "  " << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
					} else {
						buf << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
					}
					if ( !(*it)->_enabled )
						buf << "{x";
				    f++;
				    if ( f == 5 ) {
						buf << "\n\r";
						f = 0;
					}
				}
			}
		}
		if ( f != 0 && f != 5 )
			buf << "\n\r";
		f = 0;
		buf << "\n\r\t{cgod (level " << GOD << "){x\n\r";
		for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it ) {
			if ( (*it)->_level == GOD ) {
				if ( (*it)->_omniset ) {
					if ( !(*it)->_enabled )
						buf << "{w";
					if ( f == 0 ) {
						buf << "  " << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
					} else {
						buf << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
					}
					if ( !(*it)->_enabled )
						buf << "{x";
				    f++;
				    if ( f == 5 ) {
						buf << "\n\r";
						f = 0;
					}
				}
			}
		}
		if ( f != 0 && f != 5 )
			buf << "\n\r";
		f = 0;
		buf << "\n\r\t{cbuilder (level " << BUILDER << "){x\n\r";
		for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it ) {
			if ( (*it)->_level == BUILDER ) {
				if ( (*it)->_omniset ) {
					if ( !(*it)->_enabled )
						buf << "{w";
					if ( f == 0 ) {
						buf << "  " << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
					} else {
						buf << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
					}
					if ( !(*it)->_enabled )
						buf << "{x";
				    f++;
				    if ( f == 5 ) {
						buf << "\n\r";
						f = 0;
					}
				}
			}
		}
		if ( f != 0 && f != 5 )
			buf << "\n\r";
		f = 0;
		buf << "\n\r\t{c-- Commands --{x\n\r";
		for ( it = CommandTable::Instance()._commands.begin(); it != CommandTable::Instance()._commands.end(); ++it ) {
			if ( (*it)->_level == 1 ) {
				if ( (*it)->_omniset ) {
					if ( !(*it)->_enabled )
						buf << "{w";
					if ( f == 0 ) {
						buf << "  " << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
					} else {
						buf << (*it)->_name.c_str() << spaces( 12, (*it)->_name.c_str(), temp );
					}
					if ( !(*it)->_enabled )
						buf << "{x";
				    f++;
				    if ( f == 5 ) {
						buf << "\n\r";
						f = 0;
					}
				}
			}
		}
		if ( f != 0 && f != 5 )
			buf << "\n\r";

		c->Send( buf );
		return false;
	}

	if ( ( cmd = CommandTable::Instance().FindCommand( c, args, false ) ) == NULL )
		buf << "Command not found.\n\r";
	else {
		cmd->_omniset = !cmd->_omniset;
		buf << "Command '" << cmd->_name << "' toggled.\n\r";
		std::string tmp = "Omniset the command \"";
		tmp << cmd->_name << "\" to " << cmd->_omniset;
		log( c->getName(), c->getLevel(), tmp );
	}

	c->Send( buf );
	return true;
}

CmdOpen::CmdOpen() {
	SetName( "open" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdOpen::Execute( Character* c, const string& args ) {
	string buf;

	if ( args.empty() ) {
		c->Send( "Which door do you wish to open?\n\r" );
		return true;
	}

	if ( strcmp( args.c_str(), "north" ) == 0 || strcmp( args.c_str(), "n" ) == 0 ) {
		if ( !c->getRoom()->GetExit( NORTH ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( NORTH ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( NORTH ).GetOpen() ) {
			c->Send( "That door is already open.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( NORTH ).GetLocked() ) {
			c->Send( "That door is locked.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( NORTH ).SetOpen( true );
		World::Instance().FindRoom( c->getRoom()->GetExit( NORTH ).GetPoint() )->GetExit( SOUTH ).SetOpen( true );
		c->Send( "You have opened the door.\n\r" );
		return true;
	}
	if ( strcmp( args.c_str(), "east" ) == 0 || strcmp( args.c_str(), "e" ) == 0 ) {
		if ( !c->getRoom()->GetExit( EAST ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( EAST ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( EAST ).GetOpen() ) {
			c->Send( "That door is already open.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( EAST ).GetLocked() ) {
			c->Send( "That door is locked.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( EAST ).SetOpen( true );
		World::Instance().FindRoom( c->getRoom()->GetExit( EAST ).GetPoint() )->GetExit( WEST ).SetOpen( true );
		c->Send( "You have opened the door.\n\r" );
		return true;
	}
	if ( strcmp( args.c_str(), "south" ) == 0 || strcmp( args.c_str(), "s" ) == 0 ) {
		if ( !c->getRoom()->GetExit( SOUTH ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( SOUTH ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( SOUTH ).GetOpen() ) {
			c->Send( "That door is already open.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( SOUTH ).GetLocked() ) {
			c->Send( "That door is locked.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( SOUTH ).SetOpen( true );
		World::Instance().FindRoom( c->getRoom()->GetExit( SOUTH ).GetPoint() )->GetExit( NORTH ).SetOpen( true );
		c->Send( "You have opened the door.\n\r" );
		return true;
	}
	if ( strcmp( args.c_str(), "west" ) == 0 || strcmp( args.c_str(), "w" ) == 0 ) {
		if ( !c->getRoom()->GetExit( WEST ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( WEST ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( WEST ).GetOpen() ) {
			c->Send( "That door is already open.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( WEST ).GetLocked() ) {
			c->Send( "That door is locked.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( WEST ).SetOpen( true );
		World::Instance().FindRoom( c->getRoom()->GetExit( WEST ).GetPoint() )->GetExit( EAST ).SetOpen( true );
		c->Send( "You have opened the door.\n\r" );
		return true;
	}
	if ( strcmp( args.c_str(), "up" ) == 0 || strcmp( args.c_str(), "u" ) == 0 ) {
		if ( !c->getRoom()->GetExit( UP ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( UP ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( UP ).GetOpen() ) {
			c->Send( "That door is already open.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( UP ).GetLocked() ) {
			c->Send( "That door is locked.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( UP ).SetOpen( true );
		World::Instance().FindRoom( c->getRoom()->GetExit( UP ).GetPoint() )->GetExit( DOWN ).SetOpen( true );
		c->Send( "You have opened the door.\n\r" );
		return true;
	}
	if ( strcmp( args.c_str(), "down" ) == 0 || strcmp( args.c_str(), "d" ) == 0 ) {
		if ( !c->getRoom()->GetExit( DOWN ).GetThere() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( !c->getRoom()->GetExit( DOWN ).GetDoor() ) {
			c->Send( "There is no door that way.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( DOWN ).GetOpen() ) {
			c->Send( "That door is already open.\n\r" );
			return true;
		}
		if ( c->getRoom()->GetExit( DOWN ).GetLocked() ) {
			c->Send( "That door is locked.\n\r" );
			return true;
		}
		c->getRoom()->GetExit( DOWN ).SetOpen( true );
		World::Instance().FindRoom( c->getRoom()->GetExit( DOWN ).GetPoint() )->GetExit( UP ).SetOpen( true );
		c->Send( "You have opened the door.\n\r" );
		return true;
	}
	return true;
}

CmdPassword::CmdPassword() {
	SetName( "password" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdPassword::Execute( Character* c, const string& args ) {
	std::string oldP;
	std::string newP;
	std::string confirmP;

	split( args, oldP, newP, confirmP );

	if ( oldP.empty() || newP.empty() || confirmP.empty() ) {
		c->Send( "syntax: <old password> <new password> <confirm password>\n\r" );
		return false;
	}

	if ( oldP != c->GetPword() ) {
		c->Send( "Incorrect password.\n\r" );
		return false;
	}
	if ( newP != confirmP ) {
		c->Send( "Passwords do not match.\n\r" );
		return false;
	}

	c->SetPword( newP.c_str() );
	c->Send( "Password changed.\n\r" );

	return true;
}

CmdPedit::CmdPedit() {
	SetName( "pedit" );
	SetLevel( GOD );
	SetEnabled( true );
	SetOmniset( true );
}

bool CmdPedit::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string tmp = args;
	Character* ch = 0;

	ltrim( tmp, tmp );
	rtrim( tmp, tmp );

	if ( ( ch = World::Instance().FindCharacter( tmp ) ) == NULL ) {
		c->Send( "Couldn't find that target.\n\r" );
		return false;
	}

	c->setCharacter( ch );
	c->SetStatus( PEDIT );
	buf << "You are now editing " << ch->getName() << "\n\r";
	c->Send( buf );

	return true;
}

CmdPoofin::CmdPoofin() {
	SetName( "poofin" );
	SetLevel( BUILDER );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdPoofin::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string poof;

	if ( args.empty() ) {
		c->Send( " >> \"poofin\" changes the text displayed to other characters when you enter a room via 'goto'.\n\r\n\rsyntax: poofin <message> (to change poofin)\n\r        poofin -         (to remove poofin)\n\r" );
		return false;
	}
	if ( args == "-" ) {
		c->getPoofin().clear();
		c->Send( "Your poofin has been disabled.\n\r" );
		return true;
	}

	poof = args;
	rtrim( poof, poof );
	c->setPoofin( poof );
	buf << "Your poofin has been set to:\n\r" << poof << "\n\r";

	c->Send( buf );

	return true;
}

CmdPoofout::CmdPoofout() {
	SetName( "poofout" );
	SetLevel( BUILDER );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdPoofout::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string poof;

	if ( args.empty() ) {
		c->Send( " >> \"poofout\" changes the text displayed to other characters when you leave a room via 'goto'.\n\r\n\rsyntax: poofout <message> (to change poofout)\n\r        poofout -         (to remove poofout)\n\r" );
		return false;
	}
	if ( args == "-" ) {
		c->getPoofout().clear();
		c->Send( "Your poofout has been disabled.\n\r" );
		return true;
	}

	poof = args;
	rtrim( poof, poof );
	c->setPoofout( poof );
	buf << "Your poofout has been set to:\n\r" << poof << "\n\r";

	c->Send( buf );

	return true;
}

CmdPoofs::CmdPoofs() {
	SetName( "poofs" );
	SetLevel( BUILDER );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdPoofs::Execute( Character* c, const string& args ) {
	std::string buf;

	if ( c->getPoofin().empty() )
		buf << "poofin: {wnot set{x\n\r";
	else
		buf << "poofin: " << c->getPoofin() << "\n\r";
	if ( c->getPoofout().empty() )
		buf << "poofout: {wnot set{x\n\r";
	else
		buf << "poofout: " << c->getPoofout() << "\n\r";

	c->Send( buf );

	return true;
}

CmdPromote::CmdPromote() {
	SetName( "promote" );
	SetLevel( GOD );
	SetEnabled( true );
	SetOmniset( true );
}

bool CmdPromote::Execute( Character* c, const string& args ) {
	std::string buf;
	std::string buf2;
	std::string name;
	std::string sLevel;
	int level = 0;
	Character* target = 0;

	split( args, name, sLevel );

	if ( name.empty() || sLevel.empty() ) {
		c->Send( " >> \"promote\" increases a characters' level.\n\rsyntax: promote <character name> <level>\n\r" );
		return false;
	}

	level = atoi( sLevel.c_str() );
	if ( ( target = World::Instance().FindCharacter( name ) ) == NULL ) {
		c->Send( "That target cannot be found.\n\r" );
		return false;
	}

	if ( target->getLevel() >= level ) {
		c->Send( "That wouldn't be a promotion.\n\r" );
		return false;
	}

	if ( c->getLevel() <= target->getLevel() + 2 || c->getLevel() <= level + 2 ) {
		c->Send( "You do not have permission to do that.\n\r" );
		return false;
	}

	target->setLevel( level );

	buf << "You have promoted " << target->getName() << " to level " << target->getLevel() << "!\n\r";
	buf2 << c->getName() << " has {Gpromoted{x you to level {W" << target->getLevel() << "{x!\n\r";

	c->Send( buf );
	target->Send( buf2 );

	return true;
}

CmdPrompt::CmdPrompt( ) {
	SetName( "prompt" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdPrompt::Execute( Character* c, const string& args ) {
    string buf;
    
    if ( args.empty() ) {
    	buf << "syntax: prompt <prompt>\n\r";
		buf << "current prompt: " << c->getPrompt() << "{x\n\r\n\r";
		buf << "{cOptions{x (an option is % followed by one of the following characters)\n\r";
		buf << "\tH\tmax hp\n\r";
		buf << "\th\tcurrent hp\n\r";
		buf << "\tM\tmax mana\n\r";
		buf << "\tm\tcurrent mana\n\r";
		buf << "\tV\tmax movement\n\r";
		buf << "\tv\tcurrent movement\n\r";
		buf << "\tG\tgold held\n\r";
		buf << "\tg\tgold in bank\n\r";
		buf << "\tS\tsilver held\n\r";
		buf << "\ts\tsilver in bank\n\r";
		if ( c->getLevel() >= BUILDER ) {
			buf << "{cImmortal Options{x\n\r";
			buf << "\tr\tcurrent room vnum\n\r";
		}
    	c->Send( buf );
    	return false;
    }

	c->setPrompt( args );
	buf << "Prompt reset to " << c->formatPrompt() << "{x\n\r";
	c->Send( buf );

	return true;
}

CmdPut::CmdPut() {
	SetName( "put" );
	SetLevel( 1 );
	SetEnabled( true );
	SetOmniset( false );
}

bool CmdPut::Execute( Character* c, const std::string& args ) {
	std::string buf;
	std::string arg1, arg2;
	Object* target = 0;
	Object* container = 0;

	split( args, arg1, arg2 );

	if ( arg2.empty() ) {
		c->Send( "syntax: put <object> <container>\n\r" );
		return false;
	}

	if ( ( target = c->findObject( arg1 ) ) == NULL ) {
		c->Send( "You don't have that object.\n\r" );
		return false;
	}

	if ( ( container = c->findObject( arg2 ) ) == NULL ) {
		c->Send( "You don't have that container.\n\r" );
		return false;
	}

	c->remove( target );
	container->addItem( target );

	buf << "You put " << target->getShort() << " in " << container->getShort() << ".\n\r";
	c->Send( buf );

	return true;
}
